﻿/************************************************************
 * Session : 服务器与客户端之间的会话类
 * 
 * 说明: 
 * 会话类包含远程通讯端的状态,这些状态包括
 * 一、Socket
 * 二、报文内容
 * 三、客户端退出的类型(正常关闭,强制退出)
 * ********************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Diagnostics;

namespace ZXW.DotNet.Common.Basic.Network.Tcp
{
    public class Session : ICloneable
    {
        /// <summary>
        /// 会话Id
        /// </summary>
        private SessionId _sessionId;

        private byte[]  _Data;

        private Socket _cliSock;       

        private ExitType _exitType;

        /// <summary>
        /// 返回会话的ID
        /// </summary>
        public SessionId ID
        {
            get
            {
                return _sessionId;
            }
        }

        public byte[] Data
        {
            get
            {
                return _Data;
            }
            set
            {
                _Data = value;
            }
        }

        public Socket ClientSocket
        {
            get
            {
                return _cliSock ;
            }
        }

        /// <summary>
        /// 存取客户端的退出方式
        /// </summary>
        public ExitType TypeOfExit
        {
            get
            {
                return _exitType;
            }
            set
            {
                _exitType = value;
            }
        }


        /// <summary>
        /// 使用Socket对象的Handle值作为HashCode,
        /// 它具有良好的线性特征.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return (int)_cliSock.Handle;
        }

        /// <summary>
        /// 返回两个Session是否代表同一个客户端
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            Session rightObj = (Session)obj;

            return (int)_cliSock.Handle == (int)rightObj.ClientSocket.Handle;
        }

        /// <summary>
        /// 重载ToString()方法,返回Session对象的特征
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string result = string.Format("Session:{0},IP:{1}", _sessionId, _cliSock.RemoteEndPoint.ToString());
            return result;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cliSock">会话使用的Socket连接</param>
        public Session(Socket cliSock)
        {
            Debug.Assert(cliSock != null);
            _cliSock = cliSock;
            _sessionId = new SessionId((int)cliSock.Handle);
        }

        /// <summary>
        /// 关闭会话
        /// </summary>
        public void Close()
        {
            Debug.Assert(_cliSock != null);
            //关闭数据的接受和发送
            _cliSock.Shutdown(SocketShutdown.Both);
            //清理资源
            _cliSock.Close();
        }


        object System.ICloneable.Clone()
        {
            Session newSession = new Session(_cliSock);
            newSession.Data = _Data;
            newSession.TypeOfExit = _exitType;
            return newSession;
        }
    }
}
